Android Service的绑定流程源码分析(8.0)

本文详细分析了Android 8.0中Service的绑定流程,从开始到ActivityManagerService处理,再到ActivityThread的参与,最后阐述了AMS如何通知客户端连接Service成功的过程。
摘要由CSDN通过智能技术生成

一,写在前面

       为了更好的理解Service的绑定流程,建议先了解Activity和Service的启动流程,本篇文章将不再对一些重复的细节进行阐述。建议阅读前,可以参考如下两篇文章:

二,绑定服务的开始

       在Activity中调用bindService(intent,ServiceConnection)绑定服务,其实是调用父类ContextWrapper的bindService方法。
       ContextWrapper$bindService方法源码如下:
@Override
    public boolean bindService(Intent service, ServiceConnection conn,
            int flags) {
        return mBase.bindService(service, conn, flags);
    }
       mBase是一个Context类型的对象,mBase的值是一个ContextImpl对象。ContextImpl的实例化是在启动Activity时完成的,并作为参数传入Activity$attach方法,具体细节就点到这里吧,详情可参考 Android Activity的启动流程源码解析(8.0)。也就是说,绑定服务接着交给ContextImpl来处理。

       ContextImpl$bindService方法源码如下:
    @Override
    public boolean bindService(Intent service, ServiceConnection conn,
            int flags) {
        warnIfCallingFromSystemProcess();
        return bindServiceCommon(service, conn, flags, mMainThread.getHandler(),
                Process.myUserHandle());
    }

    //继续查看...

    private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
            handler, UserHandle user) {
	    IServiceConnection sd;
        if (conn == null) {
            throw new IllegalArgumentException("connection is null");
        }
        if (mPackageInfo != null) {
            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
        } else {
            throw new RuntimeException("Not supported in system context");
        }

	//...code

	int res = ActivityManager.getService().bindService(
                mMainThread.getApplicationThread(), getActivityToken(), service,
                service.resolveTypeIfNeeded(getContentResolver()),
                sd, flags, getOpPackageName(), user.getIdentifier());
		    
	//...code    
    }
       第5行,调用ContextImpl$bindServiceCommon方法;
       第14行,做一个ServiceConnection接口引用的判空检查;
       第17行,变量mPackageInfo是一个LoadedApk对象,在启动Activity的流程中也会用到这个类,这里做了判空检查;
       第18行,对conn也就是ServiceConnection接口进行封装,借助于一个Binder使ServiceConnection可以在进程间传递,下面会详细分析;
       第25行,ActivityManager.getService()是IActivityManager的代理对象,调用代理对象的bindService方法,会向系统服务ActivityManagerService发起请求,基于Binder机制,调用ActivityManagerService$bindService方法。至于为啥将绑定服务的操作交给AMS,可以参考文章  Android Activity的启动流程源码解析(8.0)  ,这里不再重复阐述。

       分析:
       第18行,调用了LoadedApk$getServiceDispatcher方法。 
       查看LoadedApk源码如下:
public final class LoadedApk {

    //...code

    private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices
        = new ArrayMap<>();
    
    //...code

    public final IServiceConnection getServiceDispatcher(ServiceConnection c,
            Context context, Handler handler, int flags) {
        synchronized (mServices) {
            LoadedApk.ServiceDispatcher sd = null;
            ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
            if (map != null) {
                if (DEBUG) Slog.d(TAG, "Returning existing dispatcher " + sd + " for conn " + c);
                sd = map.get(c);
            }
            if (sd == nu
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值